import 'dart:convert';
import 'dart:developer';
import 'package:dio/dio.dart';

/// 记录 HTTP 请求日志的通用方法
class HttpLogger {

  static void debug({
    int level = 2000,
    String? url,
    String? httpMethod,
    Map<String, dynamic>? header,
    String? startTime,
    String? endTime,
    String? operationType, // 如“上传”、“下载”、“请求”等
    FormData? formData,
    dynamic requestParams,
    Response? responseData,
    String? savePath,
    int indent = 2,
  }) {
    // 格式化表单和响应数据
    final formattedFormData = formData != null ? const JsonEncoder.withIndent('  ').convert(_formattedFormData(formData)) : '无';
    final formattedHeader = header != null ? const JsonEncoder.withIndent('  ').convert(header) : '无';
    final formattedRequestParams = requestParams != null ? const JsonEncoder.withIndent('  ').convert(requestParams) : '无';
    final formattedResponseData = responseData != null ? const JsonEncoder.withIndent('  ').convert(responseData.data) : '无';
    final stack = stackTrace();
    log(
        level: level,
        "\n"
            "============================================================================================================\n\n"
            "请求地址：$url\n"
            "请求方式：$httpMethod\n"
            "$operationType开始：$startTime\n"
            "$operationType结束：$endTime\n"
            "请求头：$formattedHeader\n"
            "${formData != null ? '请求表单：$formattedFormData\n' : ''}"
            "${requestParams != null ? '请求参数：$formattedRequestParams\n' : ''}"
            "响应数据：$formattedResponseData\n"
            "${savePath != null ? '保存路径：$savePath\n' : ''}\n\n"
            "$stack\n\n"
            "============================================================================================================"
    );
  }


  static Map<String, dynamic> _formattedFormData(FormData formData) {
    // 创建一个 Map 来存储表单数据
    Map<String, dynamic> formDataMap = {
      // 使用 map 直接将 fields 转换为 key-value 形式
      for (var field in formData.fields) field.key: field.value,
    };

    // 解析文件部分并加入到 formDataMap
    for (var element in formData.files) {
      int fileSizeInBytes = element.value.length; // 获取文件大小（字节）
      String fileSize = fileSizeInBytes < 1024 * 1024
          ? '${(fileSizeInBytes / 1024).toStringAsFixed(2)} KB'
          : '${(fileSizeInBytes / (1024 * 1024)).toStringAsFixed(2)} MB';

      var fileInfo = {
        'Filename': element.value.filename,
        'ContentType': element.value.contentType.toString(),
        'Size': fileSize,
      };

      // 根据字段类型动态更新 formDataMap
      if (formDataMap[element.key] is List) {
        (formDataMap[element.key] as List).add(fileInfo);
      } else if (formDataMap[element.key] != null) {
        // 已存在单一字典时转换为列表
        formDataMap[element.key] = [formDataMap[element.key], fileInfo];
      } else {
        // 单一文件直接赋值
        formDataMap[element.key] = fileInfo;
      }
    }

    // 自定义递归 toEncodable 函数，处理嵌套的数组和 Map
    Object? toEncodable(dynamic object) {
      if (object is MultipartFile) {
        return {
          'Filename': object.filename,
          'ContentType': object.contentType.toString(),
          'Size': '${object.length} bytes'
        };
      } else if (object is Map) {
        return object.map((key, value) => MapEntry(key, toEncodable(value)));
      } else if (object is List) {
        return object.map(toEncodable).toList();
      }
      return object;
    }
    return formDataMap;
  }



  // 获取当前堆栈信息
  static String stackTrace() {
    final trace = StackTrace.current;
    final frames = trace.toString().split('\n');
    List<String> results = [];

    // 倒序遍历堆栈帧
    for (int i = frames.length - 1; i >= 0; i--) {
      final frame = frames[i];

      // 提取文件路径和行号
      final regex = RegExp(r'#\d+\s+(.+?):(\d+):(\d+)');
      final match = regex.firstMatch(frame);
      if (match != null) {
        final filePath = match.group(1);
        final lineNumber = match.group(2);
        // results.insert(0, frame);
        // results.insert(0, '$filePath:$lineNumber)');
        results.add('$filePath:$lineNumber)');
        // 如果已找到三条数据，退出循环
        if (results.length == 3) {
          break;
        }
      }
    }
    // 返回格式化字符串，如果未找到匹配项，返回空值
    return results.isNotEmpty ? results.join('\n') : 'No relevant stack trace found';
  }

}